package com.central.scheduler.api.controller;

import com.central.common.annotation.LoginUser;
import com.central.common.annotation.RequiredPermission;
import com.central.common.constant.PermissionConstants;
import com.central.common.model.Result;
import com.central.common.model.SysUser;
import com.central.scheduler.api.enums.ExecuteType;
import com.central.scheduler.api.service.IExecutorService;
import com.central.scheduler.common.Constants;
import com.central.scheduler.common.enums.*;
import com.central.scheduler.common.utils.JSONUtils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Map;

/**
 * @author Tindy
 * @date 2022/2/22
 * @describe
 */
@RestController
@Api(tags = "执行控制api")
@Slf4j
@RequestMapping("/executors")
public class ExecutorController {

    @Autowired
    private IExecutorService executorService;

    @ApiOperation(value = "执行作业流")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processDefinitionCode", value = "PROCESS_DEFINITION_CODE", required = true, dataType = "Long", example = "100"),
            @ApiImplicitParam(name = "scheduleTime", value = "SCHEDULE_TIME", required = true, dataType = "String"),
            @ApiImplicitParam(name = "failureStrategy", value = "FAILURE_STRATEGY", required = true, dataType = "FailureStrategy"),
            @ApiImplicitParam(name = "startNodeList", value = "START_NODE_LIST", dataType = "String"),
            @ApiImplicitParam(name = "taskDependType", value = "TASK_DEPEND_TYPE", dataType = "TaskDependType"),
            @ApiImplicitParam(name = "execType", value = "COMMAND_TYPE", dataType = "CommandType"),
            @ApiImplicitParam(name = "warningType", value = "WARNING_TYPE", required = true, dataType = "WarningType"),
            @ApiImplicitParam(name = "warningGroupId", value = "WARNING_GROUP_ID", required = true, dataType = "Long", example = "100"),
            @ApiImplicitParam(name = "runMode", value = "RUN_MODE", dataType = "RunMode"),
            @ApiImplicitParam(name = "processInstancePriority", value = "PROCESS_INSTANCE_PRIORITY", required = true, dataType = "Priority"),
            @ApiImplicitParam(name = "timeout", value = "TIMEOUT", dataType = "Int", example = "100"),
            @ApiImplicitParam(name = "startParams", value = "START_PARAMS", dataType = "Stirng", example = "{}"),
            @ApiImplicitParam(name = "expectedParallelismNumber", value = "EXPECTED_PARALLELISM_NUMBER", dataType = "Int", example = "8"),
            @ApiImplicitParam(name = "dryRun", value = "DRY_RUN", dataType = "Int", example = "0")

    })
    @GetMapping("/startProcessInstance")
    @RequiredPermission({PermissionConstants.DEV_USER,PermissionConstants.OPS_USER})
    public Result startProcessInstance(@ApiIgnore @LoginUser SysUser user, Long processDefinitionCode,
                                       String scheduleTime, FailureStrategy failureStrategy,
                                       String startNodeList, TaskDependType taskDependType,
                                       CommandType execType, WarningType warningType,
                                       Long warningGroupId, RunMode runMode,
                                       Priority processInstancePriority, Integer timeout,String startParams,
                                       Integer expectedParallelismNumber,Integer dryRun){
        if (timeout == null) {
            timeout = Constants.MAX_TASK_TIMEOUT;
        }
        Map<String, String> startParamMap = null;
        if (startParams != null) {
            startParamMap = JSONUtils.toMap(startParams);
        }
        return executorService.execProcessInstance(user,processDefinitionCode,scheduleTime,
                execType,failureStrategy,startNodeList,taskDependType,warningType,warningGroupId,
                runMode,processInstancePriority,timeout,startParamMap,expectedParallelismNumber,dryRun);
    }

    /**
     * do action to process instance：pause, stop, repeat, recover from pause, recover from stop
     *
     * @param user login user
     * @param processInstanceId process instance id
     * @param executeType execute type
     * @return execute result code
     */
    @ApiOperation(value = "execute", notes = "EXECUTE_ACTION_TO_PROCESS_INSTANCE_NOTES")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "processInstanceId", value = "PROCESS_INSTANCE_ID", required = true, dataType = "Long", example = "100"),
            @ApiImplicitParam(name = "executeType", value = "EXECUTE_TYPE", required = true, dataType = "ExecuteType")
    })
    @PostMapping(value = "/execute")
    @RequiredPermission({PermissionConstants.DEV_USER,PermissionConstants.OPS_USER})
    public Result execute(@ApiIgnore @LoginUser SysUser user, Long processInstanceId, ExecuteType executeType
    ) {
        return  executorService.execute(user, processInstanceId, executeType);
    }

}
